package com.ds.iot.home;

import com.ds.common.JDSException;
import com.ds.config.ErrorListResultModel;
import com.ds.config.ErrorResultModel;
import com.ds.config.ListResultModel;
import com.ds.config.ResultModel;
import com.ds.esb.util.EsbFactory;
import com.ds.home.client.AppClient;
import com.ds.home.engine.HomeServer;
import com.ds.iot.*;
import com.ds.iot.ct.CtIotFactory;
import com.ds.iot.home.XUIPlace;
import com.ds.server.JDSClientService;
import com.ds.web.util.PageUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.ArrayList;
import java.util.List;

@Controller
@RequestMapping("/iot/app")
public class IotAppService {


    @RequestMapping(value = {"/bindArea"}, method = {RequestMethod.GET, RequestMethod.POST})
    public @ResponseBody
    ResultModel<Boolean> bindArea(String areaId, String ieee) {
        ResultModel<Boolean> userStatusInfo = new ResultModel<Boolean>();
        try {
            Area area = CtIotFactory.getCtIotService().getAreaById(areaId);
            CtIotFactory.getAdminClient().bindingSensor(ieee, areaId);
        } catch (JDSException e) {
            userStatusInfo = new ErrorResultModel();
            ((ErrorResultModel) userStatusInfo).setErrcode(e.getErrorCode());
            ((ErrorResultModel) userStatusInfo).setErrdes(e.getMessage());
        }


        return userStatusInfo;
    }


    @RequestMapping(value = {"/getAreaTree"}, method = {RequestMethod.GET, RequestMethod.POST})
    public @ResponseBody
    ResultModel<XUIPlace> getAreaTree() {
        ResultModel<XUIPlace> userStatusInfo = new ResultModel<XUIPlace>();
        try {
            Place place = CtIotFactory.getCtIotService().getPlaceById("root");
            XUIPlace xuiPlace = new XUIPlace(place, true);
            userStatusInfo.setData(xuiPlace);
        } catch (JDSException e) {
            userStatusInfo = new ErrorResultModel();
            ((ErrorResultModel) userStatusInfo).setErrcode(e.getErrorCode());
            ((ErrorResultModel) userStatusInfo).setErrdes(e.getMessage());
        }
        return userStatusInfo;
    }


    @RequestMapping(value = {"/getAreaItems"}, method = {RequestMethod.GET, RequestMethod.POST})
    public @ResponseBody
    ListResultModel<List<XUIPlace>> getAreaItems(String placeId) {
        ListResultModel<List<XUIPlace>> userStatusInfo = new ListResultModel<List<XUIPlace>>();
        try {
            Place place = CtIotFactory.getCtIotService().getPlaceById(placeId);
            if (place != null) {
                userStatusInfo = PageUtil.getDefaultPageList(place.getAreas(), XUIPlace.class);
            }

        } catch (JDSException e) {
            userStatusInfo = new ErrorListResultModel();
            ((ErrorListResultModel) userStatusInfo).setErrcode(e.getErrorCode());
            ((ErrorListResultModel) userStatusInfo).setErrdes(e.getMessage());
        }
        return userStatusInfo;
    }


    @RequestMapping(value = {"/getPlaceTree"}, method = {RequestMethod.GET, RequestMethod.POST})
    public @ResponseBody
    ResultModel<XUIPlace> getPlaceTree() {
        ResultModel<XUIPlace> userStatusInfo = new ResultModel<XUIPlace>();
        try {
            Place place = CtIotFactory.getCtIotService().getPlaceById("root");
            XUIPlace xuiPlace = new XUIPlace(place, false);
            userStatusInfo.setData(xuiPlace);
        } catch (JDSException e) {
            userStatusInfo = new ErrorResultModel();
            ((ErrorResultModel) userStatusInfo).setErrcode(e.getErrorCode());
            ((ErrorResultModel) userStatusInfo).setErrdes(e.getMessage());
        }
        return userStatusInfo;
    }


    @RequestMapping(value = {"/getPlaces"}, method = {RequestMethod.GET, RequestMethod.POST})
    public @ResponseBody
    ResultModel<XUIPlace> getPlaces() {
        ResultModel<XUIPlace> userStatusInfo = new ResultModel<XUIPlace>();
        try {
            Place place = CtIotFactory.getCtIotService().getPlaceById("root");
            XUIPlace xuiPlace = new XUIPlace(place, false);

            userStatusInfo.setData(xuiPlace);

        } catch (JDSException e) {
            userStatusInfo = new ErrorResultModel();
            ((ErrorResultModel) userStatusInfo).setErrcode(e.getErrorCode());
            ((ErrorResultModel) userStatusInfo).setErrdes(e.getMessage());
        }


        return userStatusInfo;
    }

    @RequestMapping(value = {"/saveArea"}, method = {RequestMethod.GET, RequestMethod.POST})
    public @ResponseBody
    ResultModel<Boolean> saveArea(@RequestBody Area area) {
        ResultModel<Boolean> userStatusInfo = new ResultModel<Boolean>();
        try {
            String areaId = area.getAreaid();
            if (areaId != null && !areaId.equals("")) {
                Area rarea = CtIotFactory.getCtIotService().getAreaById(areaId);
                if (rarea != null) {
                    rarea.setName(area.getName());
                    rarea.setMemo(area.getMemo());
                    CtIotFactory.getAdminClient().updateArea(rarea);
                }
            } else {
                Area rarea = CtIotFactory.getAdminClient().createArea(area.getName(), area.getPlaceid());
                rarea.setMemo(rarea.getMemo());
                CtIotFactory.getAdminClient().updateArea(rarea);
            }


        } catch (JDSException e) {
            userStatusInfo = new ErrorResultModel();
            ((ErrorResultModel) userStatusInfo).setErrcode(e.getErrorCode());
            ((ErrorResultModel) userStatusInfo).setErrdes(e.getMessage());
        }


        return userStatusInfo;
    }


    @RequestMapping(value = {"/saveSensorInfo"}, method = {RequestMethod.GET, RequestMethod.POST})
    public @ResponseBody
    ResultModel<Boolean> saveSensorInfo(String ieee, String areaId, String alias) {
        ResultModel<Boolean> userStatusInfo = new ResultModel<Boolean>();
        try {
            DeviceEndPoint endPoint = CtIotFactory.getCtIotService().getEndPointByIeee(ieee);
            if (areaId != null && !areaId.equals("")) {
                endPoint.getDevice().setAreaid(areaId);
                Area area = CtIotFactory.getCtIotService().getAreaById(areaId);

                CtIotFactory.getAdminClient().bindingSensor(endPoint.getDevice().getSerialno(), areaId);
            }
            if (alias != null && (endPoint.getName() == null || !endPoint.getName().equals(alias))) {
                CtIotFactory.getAdminClient().updateEndPointName(ieee, alias);
            }

        } catch (JDSException e) {
            userStatusInfo = new ErrorResultModel();
            ((ErrorResultModel) userStatusInfo).setErrcode(e.getErrorCode());
            ((ErrorResultModel) userStatusInfo).setErrdes(e.getMessage());
        }
        return userStatusInfo;
    }

    @RequestMapping(value = {"/saveGatewayInfo"}, method = {RequestMethod.GET, RequestMethod.POST})
    public @ResponseBody
    ResultModel<Boolean> saveGatewayInfo(String gwieee, String placeId, String name, String personId) {
        ResultModel<Boolean> userStatusInfo = new ResultModel<Boolean>();
        try {
            CtIotFactory.getAdminClient().createGateway(gwieee, placeId, name, personId);
        } catch (JDSException e) {
            userStatusInfo = new ErrorResultModel();
            ((ErrorResultModel) userStatusInfo).setErrcode(e.getErrorCode());
            ((ErrorResultModel) userStatusInfo).setErrdes(e.getMessage());
        }

        return userStatusInfo;
    }

    /**
     * 根据网关ID获取传感器列表
     *
     * @return
     */
    @RequestMapping(value = {"/getAllSenSorByGatewayId"}, method = {RequestMethod.GET, RequestMethod.POST})
    public @ResponseBody
    ListResultModel<List<ZNode>> getAllSenSorByGatewayId(String gatewayId) { //安装地址
        ListResultModel<List<ZNode>> userStatusInfo = new ListResultModel<List<ZNode>>();
        List<ZNode> list = new ArrayList<>();
        try {
            List<ZNode> zNodes = CtIotFactory.getCtIotService().getDeviceByIeee(gatewayId).getAllZNodes();
            for (ZNode gwZnode : zNodes) {
                list.addAll(gwZnode.getChildNodeList());//所有的chuanganqi
            }
            userStatusInfo.setData(list);
        } catch (Exception e) {
            userStatusInfo = new ErrorListResultModel();
            ((ErrorListResultModel) userStatusInfo).setErrdes(e.getMessage());
        }
        return userStatusInfo;
    }

    @RequestMapping(value = {"/getAreas"}, method = {RequestMethod.GET, RequestMethod.POST})
    public @ResponseBody
    ListResultModel<List<Area>> getAreas(String placeid) {

        ListResultModel<List<Area>> userStatusInfo = new ListResultModel<List<Area>>();
        List<Area> xuiAreas = new ArrayList<Area>();
        if (placeid == null || placeid.equals("")) {
            placeid = "root";
        }

        try {
            Place place = CtIotFactory.getCtIotService().getPlaceById(placeid);
            userStatusInfo = PageUtil.getDefaultPageList(place.getAreas());

        } catch (JDSException e) {
            userStatusInfo = new ErrorListResultModel();
            ((ErrorListResultModel) userStatusInfo).setErrcode(e.getErrorCode());
            ((ErrorListResultModel) userStatusInfo).setErrdes(e.getMessage());
        }


        return userStatusInfo;
    }


    @RequestMapping(value = {"/delArea"}, method = {RequestMethod.GET, RequestMethod.POST})
    public @ResponseBody
    ResultModel<Boolean> delArea(String areaId) {
        ResultModel<Boolean> userStatusInfo = new ResultModel<Boolean>();
        try {
            CtIotFactory.getAdminClient().deleteArea(areaId);
        } catch (HomeException e) {
            userStatusInfo = new ErrorResultModel();
            ((ErrorResultModel) userStatusInfo).setErrcode(e.getErrorCode());
            ((ErrorResultModel) userStatusInfo).setErrdes(e.getMessage());
        }
        return userStatusInfo;
    }

    @RequestMapping(value = {"/delPlace"}, method = {RequestMethod.GET, RequestMethod.POST})
    public @ResponseBody
    ResultModel<Boolean> delPlace(String placeId) {
        ResultModel<Boolean> userStatusInfo = new ResultModel<Boolean>();
        try {
            CtIotFactory.getAdminClient().deletePlace(placeId);
        } catch (HomeException e) {
            userStatusInfo = new ErrorResultModel();
            ((ErrorResultModel) userStatusInfo).setErrcode(e.getErrorCode());
            ((ErrorResultModel) userStatusInfo).setErrdes(e.getMessage());
        }
        return userStatusInfo;
    }

    @RequestMapping(value = {"/getChildPlaces"}, method = {RequestMethod.GET, RequestMethod.POST})
    public @ResponseBody
    ListResultModel<List<Place>> getChildPlaces(String parentId) {
        ListResultModel<List<Place>> userStatusInfo = new ListResultModel<List<Place>>();
        List<Place> xuiPlaces = new ArrayList<Place>();
        if (parentId == null || parentId.equals("")) {
            parentId = "root";
        }


        try {
            Place place = CtIotFactory.getCtIotService().getPlaceById(parentId);

            userStatusInfo = PageUtil.getDefaultPageList(place.getChilders());

        } catch (JDSException e) {
            userStatusInfo = new ErrorListResultModel();
            ((ErrorListResultModel) userStatusInfo).setErrcode(e.getErrorCode());
            ((ErrorListResultModel) userStatusInfo).setErrdes(e.getMessage());
        }


        return userStatusInfo;
    }


    @RequestMapping(value = {"/createGateway"}, method = {RequestMethod.GET, RequestMethod.POST})
    public @ResponseBody
    ResultModel<Boolean> createGateway(String gwieee, String placeId) {
        ResultModel<Boolean> userStatusInfo = new ResultModel<Boolean>();
        try {
            List<Place> places = this.getAppClient().getAllPlace();
            if (this.getAppClient().canCreateGateway(gwieee, placeId)) {
                this.getAppClient().createGateway(gwieee, placeId);
            } else {
                userStatusInfo.setData(false);
            }


        } catch (HomeException e) {
            userStatusInfo = new ErrorResultModel();
            ((ErrorResultModel) userStatusInfo).setErrdes(e.getMessage());
        }
        return userStatusInfo;
    }


    @RequestMapping(value = {"/getAllPlaces"}, method = {RequestMethod.GET, RequestMethod.POST})
    public @ResponseBody
    ListResultModel<List<XUIPlace>> getAllPlaces() {
        ListResultModel<List<XUIPlace>> userStatusInfo = new ListResultModel<List<XUIPlace>>();
        try {
            List<Place> places = this.getAppClient().getAllPlace();
            userStatusInfo = PageUtil.getDefaultPageList(places, XUIPlace.class);
        } catch (HomeException e) {
            userStatusInfo = new ErrorListResultModel();
            ((ErrorListResultModel) userStatusInfo).setErrdes(e.getMessage());
        }
        return userStatusInfo;
    }


    @RequestMapping(value = {"/getAllGateways"}, method = {RequestMethod.GET, RequestMethod.POST})
    public @ResponseBody
    ListResultModel<List<ZNode>> getAllGateways(String placeId) {
        ListResultModel<List<ZNode>> userStatusInfo = new ListResultModel<List<ZNode>>();
        try {
            List<ZNode> gateways = this.getAppClient().getAllGatewayByPlaceId(placeId);
            userStatusInfo = PageUtil.getDefaultPageList(gateways);
        } catch (HomeException e) {
            userStatusInfo = new ErrorListResultModel();
            ((ErrorListResultModel) userStatusInfo).setErrdes(e.getMessage());
        }
        return userStatusInfo;
    }

//    @RequestMapping(value = {"/getDeviceTree"}, method = {RequestMethod.GET, RequestMethod.POST})
//    public @ResponseBody
//    ListResultModel<List<XUIGateway>> getDeviceTree(String placeId) {
//        ListResultModel<List<XUIGateway>> userStatusInfo = new ListResultModel<List<XUIGateway>>();
//
//        List<Device> devices = CtIotFactory.getAdminClient().getAllGatewayByFactory("netvox");
//
//        userStatusInfo = PageUtil.getDefaultPageList(devices,XUIGateway.class);
//
//        return userStatusInfo;
//    }


    @RequestMapping(value = {"/savePlace"}, method = {RequestMethod.GET, RequestMethod.POST})
    public @ResponseBody
    ResultModel<Boolean> savePlace(@RequestBody Place place) {
        ResultModel<Boolean> userStatusInfo = new ResultModel<Boolean>();
        try {
            String placeId = place.getPlaceid();
            if (placeId != null && !placeId.equals("")) {
                Place oplace = CtIotFactory.getCtIotService().getPlaceById(placeId);
                if (oplace != null) {
                    oplace.setName(place.getName());
                    oplace.setMemo(place.getMemo());
                    oplace.setUserid(this.getAppClient().getConnectInfo().getUserID());
                    if (place.getParentId() == null) {
                        oplace.setParentId("userdef");
                    } else {
                        oplace.setParentId(place.getParentId());
                    }

                    CtIotFactory.getAdminClient().updatePlace(oplace);
                }
            } else {

                Place oplace = CtIotFactory.getAdminClient().createPlace(place.getName(), place.getParentId());
                oplace.setMemo(place.getMemo());
                oplace.setName(place.getName());
                oplace.setUserid(this.getAppClient().getConnectInfo().getUserID());
                if (place.getParentId() == null) {
                    oplace.setParentId("userdef");
                } else {
                    oplace.setParentId(place.getParentId());
                }
                CtIotFactory.getAdminClient().updatePlace(oplace);
            }


        } catch (JDSException e) {
            userStatusInfo = new ErrorResultModel();
            ((ErrorResultModel) userStatusInfo).setErrcode(e.getErrorCode());
            ((ErrorResultModel) userStatusInfo).setErrdes(e.getMessage());
        }


        return userStatusInfo;
    }


    AppClient getAppClient() throws HomeException {
        JDSClientService clientService = EsbFactory.par("$JDSC", JDSClientService.class);
        AppClient client = HomeServer.getInstance().getAppClient(clientService);
        return client;

    }

}
